home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / ICProgKit 1.3.sit / ICProgKit1.3 / Goodies / ICRandomSignature / ICSpecificOverride.p next >
Text File  |  1995-09-12  |  12KB  |  385 lines

  1. unit ICSpecificOverride;
  2.  
  3. (* Internet Config Specific Overide Component *)
  4.  
  5. (* Routine names have an ICSO prefix for Internet Config Specific Override. *)
  6.  
  7. (* To create an IC override component you need to make a copy of this *)
  8. (* file and fill in the blanks. This is an N stage process: *)
  9.  
  10. (*  1. Make a copy of this file. *)
  11. (*  2. Change kOurComponentManufacturer to your manufacturer code. *)
  12. (*  3. Add any shared globals to the sharedGlobals record. *)
  13. (*  4. If you have shared globals then init them in ICSOInitShared. *)
  14. (*  5. If the shared globals need cleaning up then clean them ICSOCleanShared. *)
  15. (*  6. Add any instance specific globals to globalsRecord. *)
  16. (*  7. If you have globals then init them in ICSOInitGlobals. *)
  17. (*  8. If the globals need cleaning up then clean them ICSOCleanGlobals. *)
  18. (*  9. If you want to add a completely new routine or remove support *)
  19. (*     for one of the built in routines then modify ICSOCanDo accordingly. *)
  20. (* 10. Modify ICSOWhatToOverride to return the correct ProcPtr for each *)
  21. (*     routine that you override or add. *)
  22. (* 11. Write each routine. If you want the component to continue calling *)
  23. (*     through to the captured component for this routine then have your *)
  24. (*     routine return delegateThisCallErr. *)
  25. (* 12. Smirk at the wonders of Component Manager. *)
  26. (* 13. Looking inside ICGenericOverride and frown at the wonders of Component Manager. *)
  27.  
  28. (* Share and Enjoy. *)
  29.  
  30. (* Quinn *)
  31. (* 12 Feb 1995 *)
  32.  
  33. interface
  34.  
  35.     uses
  36.         Components;
  37.  
  38.     const
  39.         kOurComponentManufacturer = 'JMJ ';
  40. (* You must set this up appropriately. Things will not be good otherwise. *)
  41.  
  42.         delegateThisCallErr = $81234568;
  43. (* Return this from a component routine if you want the generic override *)
  44. (* component to pass this call through to the captured component. *)
  45.  
  46.     type
  47.         sharedGlobals = record
  48.                 delegate: Component;
  49.                 (* add your own shared globals here *)
  50.             end;
  51.         sharedGlobalsPtr = ^sharedGlobals;
  52.  
  53.         globalsRecord = record
  54.                 self: ComponentInstance;
  55.                 target: ComponentInstance;
  56.                 delegate: ComponentInstance;
  57.                 shared: sharedGlobalsPtr;
  58.                 (* add your own component specific globals here*)
  59.                 current_signature: Handle;
  60.                 default_signature: Handle;
  61.                 sig_folder_name: Str63;
  62.                 random_seed: longint;
  63.             end;
  64.         globalsPtr = ^globalsRecord;
  65.         globalsHandle = ^globalsPtr;
  66.  
  67. (* Except when otherwise noted the globals handle is *)
  68. (* locked when any of these routines are called. *)
  69.  
  70.     function ICSOInitShared (globals: globalsHandle): ComponentResult;
  71. (* This routine is called to init the shared globals. *)
  72. (* If you return an error then you should make sure your part of *)
  73. (* the shared globals are 'clean'. *)
  74.  
  75.     function ICSOCleanShared (globals: globalsHandle): ComponentResult;
  76. (* This routine is called to clean the shared globals. *)
  77. (* WARNING:  This will never been called if you're using an old version *)
  78. (* of the Component Manager. Workaround: If your specifics only bleeds *)
  79. (* small amounts of memory then don't worry. If your specifics bleeds a *)
  80. (* lot of memory or other resources (such as open files) then refuse to *)
  81. (* install with older Component Managers (I think it was fixed in v2 of the *)
  82. (* manager. *)
  83.  
  84.     function ICSOInitGlobals (globals: globalsHandle): ComponentResult;
  85. (* This routine inits the override specific fields of the component *)
  86. (* specific globals. If it returns an error then the globals must be 'clean'. *)
  87.  
  88.     function ICSOCleanGlobals (globals: globalsHandle): ComponentResult;
  89. (* This routine cleans up the component specific globals, disposing any *)
  90. (* pointers and otherwise releasing any allocated resources. *)
  91.  
  92.     function ICSOCanDo (globals: globalsHandle; selector: integer): ComponentResult;
  93. (* This routine is called in response to a component can do request. *)
  94. (* You should set component result to: *)
  95. (*   -1 if you definitely want to say that the component can't do this *)
  96. (*     0 if you definitely want to say that the component can do this *)
  97. (*     1 if you want to let the target decide *)
  98. (* WARNING: These constants are quite different from the constants *)
  99. (* used by a standard Component Manager CanDo request. *)
  100.  
  101.     function ICSOWhatToOverride (globals: globalsHandle; selector: integer): ProcPtr;
  102. (* Return nil if you do not want to override this what. *)
  103. (* Return a pointer to a procedure with the appropriate signature *)
  104. (* if you do. *)
  105. (* WARNING: globals will not necessarily be locked and may be nil!!! *)
  106.  
  107. implementation
  108.  
  109.     uses
  110.         Folders, QuickDrawRules, ICTypes, ICCAPI, ICKeys, ICComponentSelectors;
  111.  
  112.     function ICSOInitShared (globals: globalsHandle): ComponentResult;
  113.     begin
  114.         ICSOInitShared := noErr;
  115.     end; (* ICSOInitShared *)
  116.  
  117.     function ICSOCleanShared (globals: globalsHandle): ComponentResult;
  118.     begin
  119.         ICSOCleanShared := noErr;
  120.     end; (* ICSOCleanShared *)
  121.  
  122.     function ICSOInitGlobals (globals: globalsHandle): ComponentResult;
  123.         var
  124.             err: ComponentResult;
  125.             refnum: integer;
  126.             strh: StringHandle;
  127.             junk: OSErr;
  128.     begin
  129.         globals^^.random_seed := TickCount;
  130.         globals^^.current_signature := nil;
  131.         globals^^.default_signature := nil;
  132.         err := noErr;
  133.         refnum := OpenComponentResFile(Component(globals^^.self));
  134.         if refnum <= 0 then begin
  135.             err := resNotFound;
  136.         end; (* if *)
  137.         if err = noErr then begin
  138.             strh := GetString(130);
  139.             if strh = nil then begin
  140.                 err := resNotFound;
  141.             end
  142.             else begin
  143.                 globals^^.sig_folder_name := strh^^;
  144.             end; (* if *)
  145.             if err = noErr then begin
  146.                 globals^^.default_signature := Get1Resource('TEXT', 128);
  147.                 if globals^^.default_signature = nil then begin
  148.                     err := resNotFound;
  149.                 end
  150.                 else begin
  151.                     DetachResource(globals^^.default_signature);
  152.                 end; (* if *)
  153.             end; (* if *)
  154.             junk := CloseComponentResFile(refnum);
  155.         end; (* if *)
  156.         ICSOInitGlobals := err;
  157.     end; (* ICSOInitGlobals *)
  158.  
  159.     function ICSOCleanGlobals (globals: globalsHandle): ComponentResult;
  160.     begin
  161.         if globals^^.current_signature <> nil then begin
  162.             DisposeHandle(globals^^.current_signature);
  163.             globals^^.current_signature := nil;
  164.         end; (* if *)
  165.         if globals^^.default_signature <> nil then begin
  166.             DisposeHandle(globals^^.default_signature);
  167.             globals^^.default_signature := nil;
  168.         end; (* if *)
  169.         ICSOCleanGlobals := noErr;
  170.     end; (* ICSOCleanGlobals *)
  171.  
  172.     function SneakyRandom (globals: globalsHandle): integer;
  173.         (* Get a random number without disturbing the random sequence in use *)
  174.         (* by the current application. *)
  175.         var
  176.             tmp: longint;
  177.     begin
  178.         tmp := QDGlobals^.randSeed;
  179.         QDGlobals^.randSeed := globals^^.random_seed;
  180.         SneakyRandom := Random;
  181.         globals^^.random_seed := QDGlobals^.randSeed;
  182.         QDGlobals^.randSeed := tmp;
  183.     end; (* SneakyRandom *)
  184.  
  185.     procedure SafeResolveAliasFile (var fs: FSSpec);
  186.         var
  187.             isfolder, wasalias: boolean;
  188.             temp: FSSpec;
  189.             gv: longInt;
  190.             oe: OSErr;
  191.     begin
  192.         if (Gestalt(gestaltAliasMgrAttr, gv) = noErr) & (BTST(gv, gestaltAliasMgrPresent)) then begin
  193.             temp := fs;
  194.             oe := ResolveAliasFile(fs, true, isfolder, wasalias);
  195.             if oe <> noErr then begin
  196.                 fs := temp;
  197.             end;
  198.         end;
  199.     end;
  200.  
  201.     procedure ChooseRandomSignature (globals: globalsHandle);
  202.         var
  203.             cpb: CInfoPBRec;
  204.             sig: FSSpec;
  205.  
  206.         function GetNthTextFile (max_count: integer; var count: integer): OSErr;
  207.             var
  208.                 err: OSErr;
  209.                 index: integer;
  210.         begin
  211.             count := 0;
  212.             index := 1;
  213.             repeat
  214.                 cpb.ioNamePtr := @sig.name;
  215.                 cpb.ioDirID := sig.parID;
  216.                 cpb.ioVRefNum := sig.vRefNum;
  217.                 cpb.ioFDirIndex := index;
  218.                 err := PBGetCatInfoSync(@cpb);
  219.                 index := index + 1;
  220.                 if (err = noErr) and not btst(cpb.ioFlAttrib, 4) and (cpb.ioFlFndrInfo.fdType = 'TEXT') then begin
  221.                     count := count + 1;
  222.                 end; (* if *)
  223.             until (err <> noErr) or (count = max_count);
  224.             GetNthTextFile := err;
  225.         end; (* GetNthTextFile *)
  226.  
  227.         var
  228.             junk: OSErr;
  229.             texth: Handle;
  230.             err: OSErr;
  231.             ref: integer;
  232.             count: integer;
  233.             length: longint;
  234.     begin
  235.         if globals^^.current_signature <> nil then begin
  236.             DisposeHandle(globals^^.current_signature);
  237.             globals^^.current_signature := nil;
  238.         end; (* if *)
  239.         texth := nil;
  240.         sig.name := globals^^.sig_folder_name;
  241.         err := FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, sig.vRefNum, sig.parID);
  242.         if err = noErr then begin
  243.             SafeResolveAliasFile(sig);
  244.             cpb.ioNamePtr := @sig.name;
  245.             cpb.ioVRefNum := sig.vRefNum;
  246.             cpb.ioDirID := sig.parID;
  247.             cpb.ioFDirIndex := 0;
  248.             err := PBGetCatInfoSync(@cpb);
  249.         end; (* if *)
  250.         if (err = noErr) and not btst(cpb.ioFlAttrib, 4) then begin
  251.             err := dirNFErr;
  252.         end; (* if *)
  253.         if err = noErr then begin
  254.             sig.parID := cpb.ioDirID;
  255.             junk := GetNthTextFile(32767, count);
  256.             if count = 0 then begin
  257.                 err := fnfErr;
  258.             end
  259.             else begin
  260.                 count := (abs(SneakyRandom(globals)) mod count) + 1;
  261.                 err := GetNthTextFile(count, junk);
  262.             end; (* if *)
  263.         end; (* if *)
  264.         if err = noErr then begin
  265.             SafeResolveAliasFile(sig);
  266.             err := HOpen(sig.vRefNum, sig.parID, sig.name, fsRdPerm, ref);
  267.         end; (* if *)
  268.         if err = noErr then begin
  269.             err := GetEOF(ref, length);
  270.             if err = noErr then begin
  271.                 if length > 4096 then begin
  272.                     length := 4096;
  273.                 end; (* if *)
  274.                 texth := NewHandle(length);
  275.                 err := MemError;
  276.             end; (* if *)
  277.             if err = noErr then begin
  278.                 err := FSRead(ref, length, texth^);
  279.             end; (* if *)
  280.             junk := FSClose(ref);
  281.         end; (* if *)
  282.         if err <> noErr then begin
  283.             DisposeHandle(texth);
  284.             texth := nil;
  285.         end; (* if *)
  286.         if texth = nil then begin
  287.             texth := globals^^.default_signature;
  288.             err := HandToHand(texth);
  289.             if err <> noErr then begin
  290.                 texth := nil;
  291.             end; (* if *)
  292.         end; (* if *)
  293.         globals^^.current_signature := texth;
  294.     end; (* ChooseRandomSignature *)
  295.  
  296.     function RSCBegin (globals: globalsHandle; perm: ICPerm): ICError;
  297.         var
  298.             err: ICError;
  299.     begin
  300.         ChooseRandomSignature(globals);
  301.         RSCBegin := delegateThisCallErr;
  302.     end; (* RSCBegin *)
  303.  
  304.     function RSCGetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  305.         var
  306.             tmpstr: Str255;
  307.             perm: icPerm;
  308.             max_size: longint;
  309.             err: ICError;
  310.     begin
  311.         if IUEqualString(key, kICSignature) = 0 then begin
  312.             (* This is for compatibility with IC 1.0, which didn't call ICBegin/ICEnd through *)
  313.             (* the target when it was done automagically because of a ICGet/SetPref call. *)
  314.             (* So if there are no permissions then we know that we're in about to do *)
  315.             (* an automagic ICBegin so we randomise the signature. *)
  316.             if (ICCGetPerm(globals^^.delegate, perm) = noErr) & (perm = icNoPerm) then begin
  317.                 ChooseRandomSignature(globals);
  318.             end; (* if *)
  319.  
  320.             max_size := size;
  321.             if globals^^.current_signature = nil then begin
  322.                 size := 0;
  323.             end
  324.             else begin
  325.                 size := GetHandleSize(globals^^.current_signature);
  326.             end; (* if *)
  327.  
  328.             err := noErr;
  329.             if ((max_size < 0) and (buf <> nil)) then begin
  330.                 err := paramErr;
  331.             end; (* if *)
  332.             if (err = noErr) and (buf <> nil) then begin
  333.                 if size > max_size then begin
  334.                     err := icTruncatedErr;
  335.                 end
  336.                 else begin
  337.                     max_size := size;
  338.                 end; (* if *)
  339.                 if max_size <> 0 then begin
  340.                     BlockMove(globals^^.current_signature^, buf, max_size);
  341.                 end; (* if *)
  342.             end; (* if *)
  343.  
  344.             attr := ICattr_locked_mask + ICattr_volatile_mask;
  345.             RSCGetPref := err;
  346.         end
  347.         else begin
  348.             RSCGetPref := delegateThisCallErr;
  349.         end; (* if *)
  350.     end; (* RSCGetPref *)
  351.  
  352.     function RSCSetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
  353.     begin
  354.         if IUEqualString(key, kICSignature) = 0 then begin
  355.             RSCSetPref := icPermErr;
  356.         end
  357.         else begin
  358.             RSCSetPref := delegateThisCallErr;
  359.         end; (* if *)
  360.     end; (* RSCSetPref *)
  361.  
  362.     function ICSOCanDo (globals: globalsHandle; selector: integer): ComponentResult;
  363.     begin
  364.         ICSOCanDo := delegateThisCallErr;
  365.     end; (* ICSOCanDo *)
  366.  
  367.     function ICSOWhatToOverride (globals: globalsHandle; selector: integer): ProcPtr;
  368.         var
  369.             proc: ProcPtr;
  370.     begin
  371.         proc := nil;
  372.         case selector of
  373.             kICCBegin: 
  374.                 proc := @RSCBegin;
  375.             kICCGetPref: 
  376.                 proc := @RSCGetPref;
  377.             kICCSetPref: 
  378.                 proc := @RSCSetPref;
  379.             otherwise
  380.                 ;
  381.         end; (* case *)
  382.         ICSOWhatToOverride := proc;
  383.     end; (* ICSOWhatToOverride *)
  384.  
  385. end. (* ICSpecificOverride *)